home *** CD-ROM | disk | FTP | other *** search
/ MIDICraft's MIDINET CD-ROM / MIDICraft's MIDINET CD-ROM.iso / DOSUTILS / KORGI3 / SENDI3.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-03  |  13.7 KB  |  657 lines

  1. // sendi3: (c) Günter Nagler 1996
  2. #include <stdio.h>
  3. #include <conio.h>
  4. #include <string.h>
  5. #include "sb.hpp"
  6. #include "korg.hpp"
  7. #include "filei3.hpp"
  8. #include <dir.h>
  9.  
  10. Soundcard* card = 0;
  11.  
  12. char* inputname = 0;
  13. unsigned char data[5000];
  14. int len = 0;
  15. int aborted = 0;
  16.  
  17. // convert into 7 bit data and send
  18. int senddumpdata(Soundcard* card, FILE* f, long pos, long len)
  19. {
  20.   if (!f || len <= 0 || !card)
  21.      return 0;
  22.  
  23.   fseek(f, pos, SEEK_SET);
  24.   if (ftell(f) != pos)
  25.     return 0;
  26.  
  27.   unsigned char data8[7];
  28.   int datalen = 0;
  29.   long sum = 0;
  30.   fprintf(stderr, "0%%  \r");
  31.   while (sum < len)
  32.   {
  33.     if (kbhit() && getch() == 27)
  34.     {
  35.       fprintf(stderr, "send aborted\n");
  36.       aborted = 1;
  37.       data[0] = 0xf7;
  38.       card->play(data, 1);
  39.       return 0;
  40.     }
  41.     if (datalen + 8 > sizeof(data))
  42.     {
  43.       if (card->play(data, datalen) != datalen)
  44.       {
  45.     fprintf(stderr, "error while sending data\n");
  46.     break;
  47.       }
  48.       fprintf(stderr, "%d%%  \r", (int)((sum * 100)/len));
  49.       datalen = 0;
  50.     }
  51.     int n = fread(data8, 1, 7, f);
  52.     if (n <= 0)
  53.       break;
  54.     sum += n;
  55.     n = code7to8(data8, n, data+datalen);
  56.     datalen += n;
  57.   }
  58.   card->play(data, datalen);
  59.   fprintf(stderr, "100%%\r");
  60.   return len == sum;
  61. }
  62.  
  63. int sendpcgdump(char* pcgfilename)
  64. {
  65.   FILE* f = fopen(pcgfilename, "rb");
  66.   if (!f)
  67.     return 0;
  68.  
  69.   data[0] = 0xf0;
  70.   data[1] = 0x42;
  71.   data[2] = 0x30;
  72.   data[3] = 0x39;
  73.   data[4] = 0x4c;
  74.  
  75.   rewind(f);
  76.   PCGHEAD head;
  77.  
  78.   if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0 || head.b1.adr != 0x58)
  79.   {
  80.     fprintf(stderr, "this is not a KORG PCG file (or a bad one)\n");
  81.     return 0;
  82.   }
  83.   printf("sending %s to KORG ...\n", inputname);
  84.   card->play(data, 5);
  85.   if (!senddumpdata(card, f, head.progdata.adr, head.progdata.len))
  86.   {
  87.     if (!aborted)
  88.       fprintf(stderr, "read error or file too short\n");
  89.     return 0;
  90.   }
  91.   data[0] = 0xf7; // eox
  92.   card->play(data, 1);
  93.   fclose(f);
  94.   return 1;
  95. }
  96.  
  97. int sendstydump(char* styfilename)
  98. {
  99.   FILE* f = fopen(styfilename, "rb");
  100.   if (!f)
  101.     return 0;
  102.  
  103.   data[0] = 0xf0;
  104.   data[1] = 0x42;
  105.   data[2] = 0x30;
  106.   data[3] = 0x39;
  107.   data[4] = 0x65;
  108.  
  109.   rewind(f);
  110.   STYHEAD head;
  111.  
  112.   if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0 || head.stylenames.adr != 0x20)
  113.   {
  114.     fprintf(stderr, "this is not a KORG STY file (or a bad one)\n");
  115.     return 0;
  116.   }
  117.  
  118.   fseek(f, 0, SEEK_END);
  119.   long flen = ftell(f);
  120.  
  121.   printf("sending %s to KORG ...\n", inputname);
  122.   card->play(data, 5);
  123.  
  124.   long datapos = head.styletable.adr;
  125.   if (!senddumpdata(card, f, datapos, flen-datapos))
  126.   {
  127.     if (!aborted)
  128.       fprintf(stderr, "read error or file too short\n");
  129.     return 0;
  130.   }
  131.   data[0] = 0xf7;
  132.   card->play(data, 1);
  133.  
  134.   fclose(f);
  135.   return 1;
  136. }
  137.  
  138. int sendarrdump(char* arrfilename)
  139. {
  140.   FILE* f = fopen(arrfilename, "rb");
  141.   if (!f)
  142.     return 0;
  143.  
  144.   data[0] = 0xf0;
  145.   data[1] = 0x42;
  146.   data[2] = 0x30;
  147.   data[3] = 0x39;
  148.   data[4] = 0x64;
  149.  
  150.   rewind(f);
  151.   ARRHEAD head;
  152.  
  153.   if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0 || head.arrnames.adr != 0x20)
  154.   {
  155.     fprintf(stderr, "this is not a KORG ARR file (or a bad one)\n");
  156.     return 0;
  157.   }
  158.  
  159.   printf("sending %s to KORG ...\n", inputname);
  160.   card->play(data, 5);
  161.  
  162.   if (!senddumpdata(card, f, head.arrdata.adr, head.arrdata.len))
  163.   {
  164.     if (!aborted)
  165.       fprintf(stderr, "read error or file too short\n");
  166.     return 0;
  167.   }
  168.   data[0] = 0xf7;
  169.   card->play(data, 1);
  170.  
  171.   fclose(f);
  172.   return 1;
  173. }
  174.  
  175. int sendbsqdump(char* bsqfilename)
  176. {
  177.   FILE* f = fopen(bsqfilename, "rb");
  178.   if (!f)
  179.     return 0;
  180.  
  181.   data[0] = 0xf0;
  182.   data[1] = 0x42;
  183.   data[2] = 0x30;
  184.   data[3] = 0x39;
  185.   data[4] = 0x66;
  186.  
  187.   rewind(f);
  188.   BSQHEAD head;
  189.  
  190.   if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0)
  191.   {
  192.     fprintf(stderr, "this is not a KORG BSQ file (or a bad one)\n");
  193.     return 0;
  194.   }
  195.  
  196.   fseek(f, 0, SEEK_END);
  197.   long flen = ftell(f);
  198.  
  199.   long steps = (flen - 2308) >> 4;
  200.   if (steps == 0)
  201.      printf("%s is empty backing sequence\n", inputname);
  202.  
  203.   data[5] = (steps & 0x7f);
  204.   data[6] = (steps >> 7);
  205.  
  206.   printf("sending %s to KORG ...\n", inputname);
  207.   card->play(data, 7);
  208.  
  209.   long datapos = 0x10;
  210.   if (!senddumpdata(card, f, datapos, flen-datapos))
  211.   {
  212.     if (!aborted)
  213.       fprintf(stderr, "read error or file too short\n");
  214.     return 0;
  215.   }
  216.   data[0] = 0xf7;
  217.   card->play(data, 1);
  218.  
  219.   fclose(f);
  220.   return 1;
  221. }
  222.  
  223. int sendsngdump(char* sngfilename)
  224. {
  225.   FILE* f = fopen(sngfilename, "rb");
  226.   if (!f)
  227.     return 0;
  228.  
  229.   data[0] = 0xf0;
  230.   data[1] = 0x42;
  231.   data[2] = 0x30;
  232.   data[3] = 0x39;
  233.   data[4] = 0x48;
  234.  
  235.   rewind(f);
  236.   SNGHEAD head;
  237.  
  238.   if (fread(&head, sizeof(head), 1, f) != 1 || strncmp(head.korg, "KORG", 4) != 0)
  239.   {
  240.     fprintf(stderr, "this is not a KORG SNG file (or a bad one)\n");
  241.     return 0;
  242.   }
  243.  
  244.   fseek(f, 0, SEEK_END);
  245.   long flen = ftell(f);
  246.  
  247.   long steps = (flen - 3718) >> 4;
  248.   if (steps == 0)
  249.      printf("%s is empty song\n", inputname);
  250.  
  251.   data[5] = (steps & 0x7f);
  252.   data[6] = (steps >> 7);
  253.  
  254.   printf("sending %s to KORG ...\n", inputname);
  255.   card->play(data, 7);
  256.  
  257.   long datapos = 0x10;
  258.   if (!senddumpdata(card, f, datapos, flen-datapos))
  259.   {
  260.     if (!aborted)
  261.       fprintf(stderr, "read error or file too short\n");
  262.     return 0;
  263.   }
  264.   data[0] = 0xf7;
  265.   card->play(data, 1);
  266.  
  267.   fclose(f);
  268.   return 1;
  269. }
  270.  
  271. int sendglbdump(char* glbfilename)
  272. {
  273.   FILE* f = fopen(glbfilename, "rb");
  274.   if (!f)
  275.     return 0;
  276.  
  277.   data[0] = 0xf0;
  278.   data[1] = 0x42;
  279.   data[2] = 0x30;
  280.   data[3] = 0x39;
  281.   data[4] = 0x51;
  282.  
  283.   rewind(f);
  284.  
  285.   fseek(f, 0, SEEK_END);
  286.   long flen = ftell(f);
  287.   if (flen != 28)
  288.   {
  289.     fprintf(stderr, "this is not a KORG GLB file (or a bad one)\n");
  290.     return 0;
  291.   }
  292.  
  293.   printf("sending %s to KORG ...\n", inputname);
  294.   card->play(data, 5);
  295.  
  296.   if (!senddumpdata(card, f, 0, flen))
  297.   {
  298.     if (!aborted)
  299.       fprintf(stderr, "read error or file too short\n");
  300.     return 0;
  301.   }
  302.   data[0] = 0xf7;
  303.   card->play(data, 1);
  304.   fclose(f);
  305.   return 1;
  306. }
  307.  
  308. int senddktdump(char* dktfilename)
  309. {
  310.   FILE* f = fopen(dktfilename, "rb");
  311.   if (!f)
  312.     return 0;
  313.  
  314.   data[0] = 0xf0;
  315.   data[1] = 0x42;
  316.   data[2] = 0x30;
  317.   data[3] = 0x39;
  318.   data[4] = 0x52;
  319.  
  320.   rewind(f);
  321.  
  322.   fseek(f, 0, SEEK_END);
  323.   long flen = ftell(f);
  324.   if (flen != 840)
  325.   {
  326.     fprintf(stderr, "this is not a KORG DKT file (or a bad one)\n");
  327.     return 0;
  328.   }
  329.  
  330.   printf("sending %s to KORG ...\n", inputname);
  331.   card->play(data, 5);
  332.  
  333.   if (!senddumpdata(card, f, 0, flen))
  334.   {
  335.     if (!aborted)
  336.       fprintf(stderr, "read error or file too short\n");
  337.     return 0;
  338.   }
  339.   data[0] = 0xf7;
  340.   card->play(data, 1);
  341.   fclose(f);
  342.   return 1;
  343. }
  344.  
  345. void checkresponse()
  346. {
  347. #define RETRY   1000
  348.  
  349.   card->startinput();
  350.  
  351.   for (long i = 0; i < RETRY; i++)
  352.   if (card->hear(data, 1))
  353.      break;
  354.   if (i == RETRY)
  355.     fprintf(stderr, "Warning: no response from KORG. Transfer might not work.\n");
  356.   else
  357.     fprintf(stderr, "KORG responded\n");
  358.  
  359.   card->stopinput();
  360. }
  361.  
  362. char* getext(char* filename)
  363. {
  364.   char* ext = strrchr(filename, '.');
  365.   if (ext)
  366.     return ext+1;
  367.   return filename + strlen(filename);
  368. }
  369.  
  370. int senddump(char* filename)
  371. {
  372. int ret;
  373.  
  374.   inputname = filename;
  375.   char* ext = getext(filename);
  376.   if (!*ext)
  377.     return 0;
  378.   if (stricmp(ext, "pcg") == 0)
  379.   {
  380.     ret = sendpcgdump(filename);
  381.   }
  382.   else if (stricmp(ext, "sty") == 0)
  383.   {
  384.     ret = sendstydump(filename);
  385.   }
  386.   else if (stricmp(ext, "arr") == 0)
  387.   {
  388.     ret = sendarrdump(filename);
  389.   }
  390.   else if (stricmp(ext, "bsq") == 0)
  391.   {
  392.     ret = sendbsqdump(filename);
  393.   }
  394.   else if (stricmp(ext, "sng") == 0)
  395.   {
  396.     ret = sendsngdump(filename);
  397.   }
  398.   else if (stricmp(ext, "glb") == 0)
  399.   {
  400.     ret = sendglbdump(filename);
  401.   }
  402.   else if (stricmp(ext, "dkt") == 0)
  403.   {
  404.     ret = senddktdump(filename);
  405.   }
  406.   else
  407.   {
  408.     fprintf(stderr, "%s: cannot handle this file\n", filename);
  409.     return 0;
  410.   }
  411.   if (!ret)
  412.      return ret;
  413.   // check if korg answers
  414.   card->startinput();
  415.   unsigned char c;
  416.   for (int i = 0; i < 1000; i++)
  417.     if (card->hear(&c, 1) && c == 0xf0)
  418.       break;
  419.  
  420.   if (c == 0xf0)
  421.   {
  422.      printf("korg answered: ");
  423.      int len = 0;
  424.      data[len++] = c;
  425.      while (len < sizeof(data) && card->hear(&c, 1) && c != 0xf7 && (kbhit() == 0 || getch() != 27))
  426.        data[len++] = c;
  427.      if (c == 0xf7)
  428.        data[len++] = c;
  429.  
  430.      if (data[4] == 0x26)
  431.        printf("data format error\n");
  432.      else if (data[4] == 0x23)
  433.        printf("data load completed\n");
  434.      else
  435.      {
  436.        for (int i = 0; i < len; i++)
  437.      printf(" %02X", data[i]);
  438.        printf("\nsee korg manual for meaning of this system exclusive message\n");
  439.      }
  440.   }
  441.   card->stopinput();
  442.   return ret;
  443. }
  444.  
  445. int iskorgext(char* ext)
  446. {
  447.   if (stricmp(ext, "pcg") == 0)
  448.     return 1;
  449.   if (stricmp(ext, "sty") == 0)
  450.     return 1;
  451.   if (stricmp(ext, "arr") == 0)
  452.     return 1;
  453.   if (stricmp(ext, "bsq") == 0)
  454.     return 1;
  455.   if (stricmp(ext, "sng") == 0)
  456.     return 1;
  457.   return 0;
  458. }
  459.  
  460. char glbfilename[128] = "";
  461. char dktfilename[128] = "";
  462. char pcgfilename[128] = "";
  463. char styfilename[128] = "";
  464. char arrfilename[128] = "";
  465. char sngfilename[128] = "";
  466. char bsqfilename[128] = "";
  467.  
  468. int main(int argc, char** argv)
  469. {
  470.   argc--; argv++;
  471.   while (argc > 0 && **argv == '-')
  472.   {
  473.     fprintf(stderr, "invalid option %s\n", *argv);
  474.     argc--; argv++;
  475.   }
  476.   if (argc == 0)
  477.   {
  478.      printf("usage: sendi3 filename ...\n");
  479.      printf("files are korg i3 files (pcg, sty, arr, bsq, sng) or glb, drk\n");
  480.      printf("pcg\tkorg i3 programs\n");
  481.      printf("sty\tkorg i3 styles\n");
  482.      printf("arr\tkorg i3 arrangements\n");
  483.      printf("bsq\tkorg i3 backing sequences\n");
  484.      printf("sng\tkorg i3 songs\n");
  485.      printf("glb\tkorg i3 global settings\n");
  486.      printf("drk\tkorg i3 drumkit parameters\n");
  487.      printf("dos wildcards (*, ?) can be used\n");
  488.      return 1;
  489.   }
  490.   char* ext = getext(inputname);
  491.   if (!*ext)
  492.   {
  493.     fprintf(stderr, "filename %s has no extension\n", inputname);
  494.     return 0;
  495.   }
  496.  
  497.   int ret = 0;
  498.   struct ffblk ff;
  499.   char fullname[128];
  500.  
  501.   while (argc > 0 && **argv != '-')
  502.   {
  503.     char* filename = *argv++; argc--;
  504.  
  505.     strcpy(fullname, filename);
  506.     inputname = fullname;
  507.     char* name = strrchr(fullname, '\\');
  508.     if (name)
  509.       name++;
  510.     else
  511.     {
  512.       name = strchr(fullname, ':');
  513.       if (name)
  514.      name++;
  515.       else
  516.      name = fullname;
  517.     }
  518.     int done = findfirst(fullname, & ff, 0);
  519.     if (done)
  520.     {
  521.        fprintf(stderr, "%s: no files found\n", inputname);
  522.        return 1;
  523.     }
  524.     while (done == 0)
  525.     {
  526.       strcpy(name, ff.ff_name);
  527.       strupr(fullname);
  528.  
  529.       char* ext = getext(fullname);
  530.       if (strcmp(ext, "GLB") == 0)
  531.       {
  532.     if (*glbfilename != 0 && strcmp(fullname, glbfilename) != 0)
  533.     {
  534.       fprintf(stderr, "cannot send more than one global data (%s,%s)\n", fullname, glbfilename);
  535.       return 1;
  536.     }
  537.     strcpy(glbfilename, fullname);
  538.       }
  539.       else if (strcmp(ext, "DKT") == 0)
  540.       {
  541.     if (*dktfilename != 0 && strcmp(fullname, dktfilename) != 0)
  542.     {
  543.       fprintf(stderr, "cannot send more than one drumkit data (%s,%s)\n", fullname, dktfilename);
  544.       return 1;
  545.     }
  546.     strcpy(dktfilename, fullname);
  547.       }
  548.       else if (strcmp(ext, "PCG") == 0)
  549.       {
  550.     if (*pcgfilename != 0 && strcmp(fullname, pcgfilename) != 0)
  551.     {
  552.       fprintf(stderr, "cannot send more than one program data file (%s,%s)\n", fullname, pcgfilename);
  553.       return 1;
  554.     }
  555.     strcpy(pcgfilename, fullname);
  556.       }
  557.       else if (strcmp(ext, "STY") == 0)
  558.       {
  559.     if (*styfilename != 0 && strcmp(fullname, styfilename) != 0)
  560.     {
  561.       fprintf(stderr, "cannot send more than one style data file (%s,%s)\n", fullname, styfilename);
  562.       return 1;
  563.     }
  564.     strcpy(styfilename, fullname);
  565.       }
  566.       else if (strcmp(ext, "ARR") == 0)
  567.       {
  568.     if (*arrfilename != 0 && strcmp(fullname, arrfilename) != 0)
  569.     {
  570.       fprintf(stderr, "cannot send more than one arrangement data file (%s,%s)\n", fullname, arrfilename);
  571.       return 1;
  572.     }
  573.     strcpy(arrfilename, fullname);
  574.       }
  575.       else if (strcmp(ext, "BSQ") == 0)
  576.       {
  577.     if (*bsqfilename != 0 && strcmp(fullname, bsqfilename) != 0)
  578.     {
  579.       fprintf(stderr, "cannot send more than one backing sequence data file (%s,%s)\n", fullname, bsqfilename);
  580.       return 1;
  581.     }
  582.     strcpy(bsqfilename, fullname);
  583.       }
  584.       else if (strcmp(ext, "SNG") == 0)
  585.       {
  586.     if (*sngfilename != 0 && strcmp(fullname, sngfilename) != 0)
  587.     {
  588.       fprintf(stderr, "cannot send more than one song data file (%s,%s)\n", fullname, sngfilename);
  589.       return 1;
  590.     }
  591.     strcpy(sngfilename, fullname);
  592.       }
  593.       else
  594.     fprintf(stderr, "file %s ignored\n", fullname);
  595.  
  596.       if (aborted)
  597.     break;
  598.       done = findnext(&ff);
  599.     }
  600.   }
  601.  
  602.   card = detect_soundcard();
  603.   if (!card)
  604.   {
  605.     fprintf(stderr, "Could not detect soundcard\n");
  606.     return 1;
  607.   }
  608.  
  609.   checkresponse();
  610.  
  611.   if (*glbfilename)
  612.   {
  613.      int r = senddump(glbfilename);
  614.      if (r)
  615.        ret = r;
  616.   }
  617.   if (*dktfilename)
  618.   {
  619.      int r = senddump(dktfilename);
  620.      if (r)
  621.        ret = r;
  622.   }
  623.   if (*pcgfilename)
  624.   {
  625.      int r = senddump(pcgfilename);
  626.      if (r)
  627.        ret = r;
  628.   }
  629.   if (*styfilename)
  630.   {
  631.      int r = senddump(styfilename);
  632.      if (r)
  633.        ret = r;
  634.   }
  635.   if (*arrfilename)
  636.   {
  637.      int r = senddump(arrfilename);
  638.      if (r)
  639.        ret = r;
  640.   }
  641.   if (*bsqfilename)
  642.   {
  643.      int r = senddump(bsqfilename);
  644.      if (r)
  645.        ret = r;
  646.   }
  647.   if (*sngfilename)
  648.   {
  649.      int r = senddump(sngfilename);
  650.      if (r)
  651.        ret = r;
  652.   }
  653.  
  654.   delete card;
  655.   return ret;
  656. }
  657.